package org.dfl.taverna;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.biomoby.client.taverna.plugin.BiomobyScavenger;
import org.dfl.data.ConfigDirectory;
import org.dfl.data.Repository;
import org.dfl.log.Logger;
import org.dfl.plugin.DflPlugin;
import org.embl.ebi.escience.scuflworkers.beanshell.BeanshellScavenger;
import org.embl.ebi.escience.scuflworkers.biomart.BiomartScavenger;
import org.embl.ebi.escience.scuflworkers.java.LocalServiceScavenger;
import org.embl.ebi.escience.scuflworkers.soaplab.SoaplabScavenger;
import org.embl.ebi.escience.scuflworkers.wsdl.WSDLBasedScavenger;
import org.embl.ebi.escience.utils.TavernaSPIRegistry;

/**
 *
 * @author Lukas
 */
public class Taverna {

    private static final String TAVERNA_HOME_PROP = "taverna.home";
    private static Taverna instance = null;
    
    private InputStream getResource(String name) throws IOException {
    	URL url = DflPlugin.getURLFromPlugin(name);
    	return url.openStream();
    }

    private Taverna() {
        TavernaSPIRegistry.setRepository(new WrapperRepository());
        System.setProperty(TAVERNA_HOME_PROP, Repository.getInstance().getHomeFile().getAbsolutePath());
        
        ConfigDirectory conf = ConfigDirectory.getInstance();
        
        String[] resources = {"log4j.properties", "mygrid.properties"};
        
        for (String resource : resources) {
        	if (conf.getStoredFile(resource) == null) {
            	try {
            		conf.storeFile(resource, getResource("conf/" + resource));
            	} catch (IOException ex) {
            		Logger.logException(ex);
            	}
            }
        }
    }

    public static Taverna getInstance() {
        if (instance == null) {
            instance = new Taverna();
        }

        return instance;
    }

    private synchronized void addProcessorGroup(ProcessorTreeNode node, ProcessorLoadListener listener) {
        listener.processorSubtreeLoaded(this, node);
    }
    
    public void loadProcessors(final ProcessorLoadListener listener) {   	
        try {
            addProcessorGroup(new ProcessorTreeNode(new LocalServiceScavenger()), listener);
            addProcessorGroup(new ProcessorTreeNode(new BeanshellScavenger()), listener);

            Thread group1 = new Thread() {
                @Override
                public void run() {
                    try {
                        String[] biomoby = Configuration.getInstance().getDefaultBiomoby();
                        for (String str : biomoby) {
                            addProcessorGroup(new ProcessorTreeNode(new BiomobyScavenger(str)), listener);
                        }
                    } catch (Exception ex) {
                        Logger.logException(ex);
                    }
                }
            };
            
            Thread group2 = new Thread() {

                @Override
                public void run() {
                    try {
                        String[] wsdl = Configuration.getInstance().getDefaultWSDL();
                        for (String str : wsdl) {
                            addProcessorGroup(new ProcessorTreeNode(new WSDLBasedScavenger(str)), listener);
                        }
                    } catch (Exception ex) {
                        Logger.logException(ex);
                    }
                }
            };

            Thread group3 = new Thread() {

                @Override
                public void run() {
                    try {
                        String[] soaplab = Configuration.getInstance().getDefaultSoaplab();
                        for (String str : soaplab) {
                            addProcessorGroup(new ProcessorTreeNode(new SoaplabScavenger(str)), listener);
                        }
                    } catch (Exception ex) {
                        Logger.logException(ex);
                    }
                }
            };

            Thread group4 = new Thread() {

                @Override
                public void run() {
                    try {
                        String[] mart = Configuration.getInstance().getDefaultMartRegistry();
                        for (String str : mart) {
                            addProcessorGroup(new ProcessorTreeNode(new BiomartScavenger(str)), listener);
                        }
                    } catch (Exception ex) {
                        Logger.logException(ex);
                    }
                }
            };

            group1.start();
            group2.start();
            group3.start();
            group4.start();
            
            group4.join();
            group3.join();
            group2.join();
            group1.join();
        
        } catch (Exception ex) {
            Logger.logException(ex);
        }
    }
}
